package order.service;

import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.AllArgsConstructor;
import order.dto.FoodNutrition;
import order.dto.Nutrition;
import order.dto.UserNutrition;
import order.entity.PageResponse;
import order.mapper.FoodNutritionMapper;
import order.mapper.UserNutritionMapper;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import user.dto.UserDto;

import java.sql.Date;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
@AllArgsConstructor
@DubboService(version = "1.0.0")
public class UserNutritionImpl implements UserNutritionI {
    UserNutritionMapper userNutritionMapper;
    FoodNutritionMapper foodNutritionMapper;

    public PageResponse<UserNutrition> getNutrition(int userId, int pageNum) {
        LambdaQueryWrapper<UserNutrition> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserNutrition::getUserId, userId);
        Page<UserNutrition> page = new Page<>(pageNum, 5);
        Page<UserNutrition> userNutritions = userNutritionMapper.selectPage(page, queryWrapper);
        long total = userNutritionMapper.selectCount(queryWrapper);
        return new PageResponse<>(userNutritions.getRecords(), total, pageNum, 5);
    }

    public Boolean calculateUserNutrition(UserDto userDto) {
        if (userDto.getSex() == 0) {
            userDto.setEnergy(1.2 * (88.362 + (13.397 * userDto.getWeight()) + (4.799 * userDto.getHeight()) - (5.677 * userDto.getAge())));
            userDto.setCarbohydrate((float) userDto.getEnergy() / 8);
            userDto.setProtein((float) (0.8 * userDto.getEnergy()));
            userDto.setFats((float) (userDto.getEnergy() / 36));
            return true;
        } else if (userDto.getSex() == 1) {
            userDto.setEnergy(1.2 * (447.593 + (9.247 * userDto.getWeight()) + (3.098 * userDto.getHeight()) - (4.330 * userDto.getAge())));
            userDto.setCarbohydrate((float) userDto.getEnergy() / 8);
            userDto.setProtein((float) (0.8 * userDto.getEnergy()));
            userDto.setFats((float) (userDto.getEnergy() / 36));
            return true;
        } else {
            return false;
        }


    }

    public Boolean addUserNutrition(UserNutrition userNutrition) {
        userNutrition.setDate(Date.valueOf(LocalDate.now()));
        LocalDate today = LocalDate.now();

//        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");


        LambdaQueryWrapper<UserNutrition> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserNutrition::getDate, today)
                .eq(UserNutrition::getUserId, userNutrition.getUserId());
        List<UserNutrition> userNutritions = userNutritionMapper.selectList(queryWrapper);

        if (!userNutritions.isEmpty()) {
            return false;
        }
        if (userNutritionMapper.insert(userNutrition) > 0) {
            return true;
        } else {
            return false;
        }


    }

    public Boolean updateUserNutrition(UserNutrition userNutrition) {
        LocalDate today = LocalDate.now();
        LambdaQueryWrapper<UserNutrition> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserNutrition::getUserId, userNutrition.getUserId())
                .eq(UserNutrition::getDate, today);
        return userNutritionMapper.update(userNutrition, queryWrapper) > 0;
    }

    public UserNutrition changeUserNutritionByFoodId(int userId, int foodId) {
        LocalDate today = LocalDate.now();
        LambdaQueryWrapper<UserNutrition> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserNutrition::getUserId, userId)
                .eq(UserNutrition::getDate, today);
        UserNutrition userNutrition = userNutritionMapper.selectOne(queryWrapper);
        LambdaQueryWrapper<FoodNutrition> foodQueryWrapper = new LambdaQueryWrapper<>();
        foodQueryWrapper.eq(FoodNutrition::getId, foodId);
        FoodNutrition foodNutrition = foodNutritionMapper.selectOne(foodQueryWrapper);
        if (userNutrition != null) {
            userNutrition.setCarbohydrate(userNutrition.getCarbohydrate() + foodNutrition.getCarbohydrate());
            userNutrition.setProtein(userNutrition.getProtein() + foodNutrition.getProtein());
            userNutrition.setFats(userNutrition.getFats() + foodNutrition.getFats());
            userNutrition.setEnergy(userNutrition.getEnergy() + foodNutrition.getEnergy());
            updateUserNutrition(userNutrition);
            return userNutrition;
        } else {
            return null;
        }
    }


    public UserNutrition changeUserNutritionByNutrition(int userId, Nutrition nutrition) {
        LocalDate today = LocalDate.now();
        LambdaQueryWrapper<UserNutrition> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserNutrition::getUserId, userId)
                .eq(UserNutrition::getDate, today);
        UserNutrition userNutrition = userNutritionMapper.selectOne(queryWrapper);
        if (userNutrition != null) {
            userNutrition.setCarbohydrate(userNutrition.getCarbohydrate() + nutrition.getCarbohydrate());
            userNutrition.setProtein(userNutrition.getProtein() + nutrition.getProtein());
            userNutrition.setFats(userNutrition.getFats() + nutrition.getFats());
            userNutrition.setEnergy(userNutrition.getEnergy() + nutrition.getEnergy());
            userNutrition.setFiber(userNutrition.getFiber() + nutrition.getFiber());
            updateUserNutrition(userNutrition);
            return userNutrition;
        } else {
            UserNutrition userNutrition1 = new UserNutrition();
            userNutrition1.setUserId(userId);
            userNutrition1.setCarbohydrate(nutrition.getCarbohydrate());
            userNutrition1.setProtein(nutrition.getProtein());
            userNutrition1.setFats(nutrition.getFats());
            userNutrition1.setEnergy(nutrition.getEnergy());
            userNutrition1.setFiber(nutrition.getFiber());
            userNutrition1.setDate(Date.valueOf(today));
            addUserNutrition(userNutrition1);
            return userNutrition1;

        }
    }

    public UserNutrition getUserNutritionByUserId(int userId) {

        LocalDate today = LocalDate.now();
        LambdaQueryWrapper<UserNutrition> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserNutrition::getUserId, userId)
                .eq(UserNutrition::getDate, today);
        UserNutrition userNutrition = userNutritionMapper.selectOne(queryWrapper);
        return userNutrition;
    }
    @Override
    public List<UserNutrition> getUserNutrition(int userId) {
        LambdaQueryWrapper<UserNutrition> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserNutrition::getUserId, userId);
        return userNutritionMapper.selectList(queryWrapper);
    }
}
